﻿using StudentInfoSystem.Core.MockImplementations;
using StudentInfoSystem.Core.Models;
using StudentInfoSystem.Core.Models.Enums;
using StudentInfoSystem.Core.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StudentInfoSystem.Tests.MockImplementations;

[TestClass]
public sealed class MockStudentServiceTests
{
    private MockStudentService _service;
    private string _testFilePath = "students.json";

    [TestInitialize]
    public void TestInitialize()
    {
        // 创建唯一测试文件
        _testFilePath = $"testdata_{Guid.NewGuid()}.json";

        // 初始化服务
        //_service = new MockStudentService();
        //_service.SetFilePath(_testFilePath);
        //_service.InitializeMockData(); // 确保每个测试都有初始化数据
    }

    [TestCleanup]
    public void TestCleanup()
    {
        // 清理测试文件
        if (File.Exists(JsonData.GetFilePath(_testFilePath)))
        {
            File.Delete(JsonData.GetFilePath(_testFilePath));
        }
    }

    [TestMethod]
    public void InitializeMockData_WhenCalled_GeneratesAtLeast100Students()
    {

        // Assert
        var students = _service.GetAll().ToList();

        Console.WriteLine($"已生成{students.Count}名学生");
        foreach (var student in _service.GetAll().Take(10))
        {
            Console.WriteLine($"ID: {student.Id}, 姓名: {student.Name}");
        }

        Assert.IsTrue(students.Count >= 100, "应生成至少100名学生");
        Assert.IsFalse(students.Any(s => string.IsNullOrEmpty(s.Id)), "所有学生应有有效ID");
        Assert.IsFalse(students.GroupBy(s => s.Id).Any(g => g.Count() > 1), "学生ID应唯一");
    }

    [TestMethod]
    public void LoadData_ShouldLoadStudentsFromFile()
    {
        // Arrange: 创建新服务实例
        //var newService = new MockStudentService();
        //newService.SetFilePath(_testFilePath);

        //// Act: 加载数据不初始化
        //newService.LoadData(_testFilePath);
        //var students = newService.GetAll().ToList();

        //// Assert
        //Assert.IsTrue(students.Count >= 100);
    }

    [TestMethod]
    public void Add_ValidStudent_ShouldIncreaseCount()
    {
        // Arrange
        var initialCount = _service.GetAll().Count();
        var newStudent = new Student
        {
            Id = "20240001",
            Name = "测试学生",
            Gender = Gender.Male,
            College = "测试学院"
        };

        // Act
        _service.Add(newStudent);
        var updatedCount = _service.GetAll().Count();

        // Assert
        Assert.AreEqual(initialCount + 1, updatedCount);
        Assert.IsNotNull(_service.GetById("20240001"));
    }

    [TestMethod]
    [ExpectedException(typeof(ArgumentException))]
    public void Add_DuplicateId_ShouldThrowException()
    {
        // Arrange: 获取现有学生ID
        var existingId = _service.GetAll().First().Id;
        var duplicateStudent = new Student
        {
            Id = existingId,
            Name = "重复ID测试"
        };

        // Act
        _service.Add(duplicateStudent);
    }

    [TestMethod]
    public void Update_ExistingStudent_ShouldModifyData()
    {
        // Arrange
        var student = _service.GetAll().First();
        var originalName = student.Name;
        var updatedName = "修改后的姓名";

        // Act
        student.Name = updatedName;
        _service.Update(student);
        var updatedStudent = _service.GetById(student.Id);

        // Assert
        Assert.AreEqual(updatedName, updatedStudent.Name);
        Assert.AreNotEqual(originalName, updatedStudent.Name);
    }

    [TestMethod]
    [ExpectedException(typeof(KeyNotFoundException))]
    public void Update_NonExistingStudent_ShouldThrowException()
    {
        // Arrange
        var fakeStudent = new Student { Id = "99999999" };

        // Act
        _service.Update(fakeStudent);
    }

    [TestMethod]
    public void Delete_ExistingStudent_ShouldRemoveFromList()
    {
        // Arrange
        var studentToDelete = _service.GetAll().First();
        var initialCount = _service.GetAll().Count();

        // Act
        _service.Delete(studentToDelete.Id);
        var updatedCount = _service.GetAll().Count();

        // Assert
        Assert.AreEqual(initialCount - 1, updatedCount);
        Assert.IsNull(_service.GetById(studentToDelete.Id));
    }

    [TestMethod]
    [ExpectedException(typeof(KeyNotFoundException))]
    public void Delete_NonExistingId_ShouldThrowException()
    {
        // Act
        _service.Delete("99999999");
    }

    [TestMethod]
    public void Search_ByName_ShouldReturnMatches()
    {
        // Arrange
        var testName = "特殊测试姓名";
        _service.Add(new Student { Id = "20240002", Name = testName });

        var criteria = new SearchCriteria
        {
            Keyword = testName,
            Field = SearchField.Name
        };

        // Act
        _service.Search(criteria);
        var results = _service.GetAllFiltered().ToList();

        // Assert
        Assert.IsTrue(results.All(s => s.Name.Contains(testName)));
        Assert.IsTrue(results.Count > 0);
    }

    [TestMethod]
    public void Search_EmptyCriteria_ShouldReturnAll()
    {
        // Arrange
        var allStudents = _service.GetAll().ToList();
        var criteria = new SearchCriteria();

        // Act
        _service.Search(criteria);
        var results = _service.GetAllFiltered().ToList();

        // Assert
        Assert.AreEqual(allStudents.Count, results.Count);
    }

    [TestMethod]
    public void Sort_ByStudentId_ShouldOrderCorrectly()
    {
        // Arrange
        _service.Sort(SortOption.ByStudentId, true);

        // Act
        var sortedStudents = _service.GetAllFiltered().ToList();
        var first = sortedStudents.First().Id;
        var last = sortedStudents.Last().Id;

        // Assert
        Assert.IsTrue(string.Compare(first, last) < 0);
    }

    [TestMethod]
    public void GetAllFiltered_AfterSearchAndSort_ShouldReflectChanges()
    {
        // Arrange
        var testCollege = "测试排序学院";
        _service.Add(new Student { Id = "20240003", College = testCollege });
        _service.Add(new Student { Id = "20240004", College = testCollege });

        // 搜索
        _service.Search(new SearchCriteria
        {
            Keyword = testCollege,
            Field = SearchField.College
        });

        // 排序
        _service.Sort(SortOption.ByStudentId,true);

        // Act
        var results = _service.GetAllFiltered().ToList();

        // Assert
        Assert.IsTrue(results.All(s => s.College == testCollege));
        Assert.AreEqual("20240003", results.First().Id);
        Assert.AreEqual("20240004", results.Last().Id);
    }


    // 暂时没做数据持久化的打算，后续再扩充
    //[TestMethod]
    //public void DataPersistence_AfterAdd_ShouldSaveToFile()
    //{
    //    // Arrange
    //    var testId = "20240005";
    //    var newStudent = new Student
    //    {
    //        Id = testId,
    //        Name = "持久化测试"
    //    };
    //    _service.Add(newStudent);

    //    // Act: 创建新服务实例加载相同文件
    //    var newService = new MockStudentService();
    //    newService.SetFilePath(_testFilePath);
    //    newService.LoadData(_testFilePath);

    //    // Assert
    //    Assert.IsNotNull(newService.GetById(testId));
    //}
}
